package com.oos.zone.wechat.cp.service.impl;

import com.google.common.collect.ImmutableMap;
import com.oos.zone.wechat.cp.bean.MyWxCpXmlMessage;
import com.oos.zone.wechat.cp.service.WxCpEventNoticeService;
import lombok.extern.log4j.Log4j2;
import me.chanjar.weixin.cp.api.WxCpService;
import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage;
import me.chanjar.weixin.cp.bean.message.WxCpXmlOutTextMessage;
import me.chanjar.weixin.cp.config.WxCpConfigStorage;
import me.chanjar.weixin.cp.message.WxCpMessageRouter;
import me.chanjar.weixin.cp.util.crypto.WxCpCryptUtil;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Optional;

/**
 * 功能描述：企业微信消息事件处理
 *
 * @author 拓金辉
 * @version 1.0
 * @date 2021-08-11 19:11:36
 */
@Log4j2
@Service
public class WxCpEventNoticeServiceImpl implements WxCpEventNoticeService {

    /**
     * WxCpXmlOutTextMessage
     */
    public final WxCpXmlOutTextMessage defaultMessage = WxCpXmlOutMessage.TEXT().build();

    /**
     * WxCpService
     */
    @Resource
    private WxCpService wxCpService;

    /**
     * WxCpMessageRouter
     */
    @Resource
    private WxCpMessageRouter wxCpMessageRouter;

    /**
     * 方法描述：微信通知事件
     *
     * @param corpId       路径参数，企业id
     * @param agentId      路径参数，应用id
     * @param msgSignature 从接收消息的URL中获取的msg_signature参数企业微信加密签名，msg_signature结合了企业填写的token、请求中的timestamp、nonce参数、加密的消息体
     * @param timestamp    从接收消息的URL中获取的timestamp参数
     * @param nonce        从接收消息的URL中获取的nonce参数
     * @param encryptedXml 从接收消息的URL中获取的整个post数据
     * @return java.lang.String
     * @author 拓金辉
     * @date 2021-07-30 14:37:07
     */
    @Override
    public String notice(String corpId, String agentId, String msgSignature, String timestamp, String nonce, String encryptedXml) {
        final WxCpConfigStorage wxCpConfigStorage = wxCpService.getWxCpConfigStorage();
        final MyWxCpXmlMessage wxCpXmlMessage = MyWxCpXmlMessage.fromEncryptedXml(encryptedXml, wxCpConfigStorage, timestamp, nonce, msgSignature);
        final ImmutableMap<String, Object> context = ImmutableMap.of("corpId", corpId, "agentId", Integer.parseInt(agentId));
        return Optional.ofNullable(wxCpMessageRouter.route(wxCpXmlMessage, context)).orElse(defaultMessage).toEncryptedXml(wxCpConfigStorage);
    }

    /**
     * 方法描述：验证URL有效性
     *
     * @param corpId       路径参数，企业id
     * @param agentId      路径参数，应用id
     * @param msgSignature 从接收消息的URL中获取的msg_signature参数企业微信加密签名，msg_signature结合了企业填写的token、请求中的timestamp、nonce参数、加密的消息体
     * @param timestamp    从接收消息的URL中获取的timestamp参数
     * @param nonce        从接收消息的URL中获取的nonce参数
     * @param echoStr      从接收消息的URL中获取的echostr参数
     * @return java.lang.String
     * @author 拓金辉
     * @date 2021-07-30 14:37:07
     */
    @Override
    public String verify(String corpId, String agentId, String msgSignature, String timestamp, String nonce, String echoStr) {
        final WxCpConfigStorage wxCpConfigStorage = wxCpService.getWxCpConfigStorage();
        return wxCpService.checkSignature(msgSignature, timestamp, nonce, echoStr) ? new WxCpCryptUtil(wxCpConfigStorage).decrypt(echoStr) : "验证URL失败";
    }

}
